<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" content="chrome=1, IE=edge" http-equiv="X-UA-Compatible" />
  
    <title>WWT Web Client Messier Objects</title>
    <script src="http://www.worldwidetelescope.org/webclient/sdk/wwtsdk.js"></script>   
    <script>

    // Create the WorldWide telescope object variable

    var wwt;

    // Create variables to hold the changeable settings

    var bShowCrosshairs = true;
    var bShowUI = true;
    var current = 0;
    var currentIndex = 0;

    var index = [];  

    //  **********************************************************************
    //
    //
    //                              Messier Objects
    //
    //
    //  **********************************************************************

    var MessierData = [
    
['M1 Crab Nebula',83.625,22.01667,'Supernova remnant',8.4],
['M2',323.375,-0.8166667,'Globular cluster',6.5],
['M3',205.55,28.38333,'Globular cluster',6.4],
['M4',245.9,-26.53333,'Globular cluster',5.9],
['M5',229.65,2.083333,'Globular cluster',5.8],
['M6 Butterfly Cluster',265.025,-32.21667,'Open cluster',4.2],
['M7 Ptolemy\'s Cluster',268.475,-34.81667,'Open cluster',3.3],
['M8 Lagoon Nebula',270.95,-24.38333,'Starforming nebula',5.8],
['M9',259.8,-18.51667,'Globular cluster',7.9],
['M10',254.275,-4.1,'Globular cluster',6.6],
['M11 Wild Duck Cluster',282.775,-6.266667,'Open cluster',5.8],
['M12',251.8,-1.95,'Globular cluster',6.6],
['M13 Hercules Cluster',250.425,36.46667,'Globular cluster',5.9],
['M14',264.4,-3.25,'Globular cluster',7.6],
['M15 Cumulo de Pegaso',322.5,12.16667,'Globular cluster',6.4],
['M16 Eagle Nebula (part)',274.7,-13.78333,'Starforming nebula',6],
['M17 Omega Nebula',275.2,-16.18333,'Starforming nebula',7],
['M18',274.975,-17.13333,'Open cluster',6.9],
['M19',255.65,-26.26667,'Globular cluster',7.2],
['M20 Trifid Nebula',270.65,-23.03333,'Starforming nebula',8.5],
['M21',271.15,-22.5,'Open cluster',5.9],
['M22 Sagittarius Cluster',279.1,-23.9,'Globular cluster',5.1],
['M23',269.2,-19.01667,'Open cluster',5.5],
['M24 Sagittarius Star Cloud',274.225,-18.48333,'Star cloud',4.5],
['M25',277.9,-19.25,'Open cluster',4.6],
['M26',281.3,-9.4,'Open cluster',8],
['M27 Dumbbell Neblua',299.9,22.71667,'Planetary nebula',8.1],
['M28',276.125,-24.86667,'Globular cluster',6.9],
['M29',305.975,38.53333,'Open cluster',6.6],
['M30',325.1,-23.18333,'Globular cluster',7.5],
['M31 Andromeda Galaxy',10.675,41.26667,'Spiral galaxy',3.4],
['M32',10.675,40.86666,'Dwarf elliptical galaxy',8.2],
['M33 Triangulum Galaxy',23.475,30.65,'Spiral galaxy',5.7],
['M34',40.5,42.78333,'Open cluster',5.2],
['M35',92.22501,24.33333,'Open cluster',5.1],
['M36',84.02499,34.13334,'Open cluster',6],
['M37',88.1,32.55,'Open cluster',5.6],
['M38',82.175,35.83333,'Open cluster',6.4],
['M39',323.05,48.43333,'Open cluster',4.6],
['M40 Winnecke 4',185.6,58.08333,'Double star',8],
['M41',101.75,-20.73333,'Open cluster',4.5],
['M42 Orion Nebula',83.85001,-5.45,'Starforming nebula',4],
['M43 de Mairan\'s Nebula',83.9,-5.266667,'Starforming nebula',9],
['M44 Beehive Cluster',130.025,19.98333,'Open cluster',3.1],
['M45 Pleiades - Seven Sisters',56.75,24.11667,'Open cluster',1.2],
['M46',115.45,-14.81667,'Open cluster',6.1],
['M47',114.15,-14.5,'Open cluster',4.4],
['M48',123.45,-5.8,'Open cluster',5.8],
['M49',187.45,8,'Elliptical galaxy',8.4],
['M50',105.8,-8.333333,'Open cluster',5.9],
['M51 Whirlpool Galaxy',202.475,47.2,'Spiral galaxy',8.1],
['M52',351.05,61.58333,'Open cluster',6.9],
['M53',198.225,18.16667,'Globular cluster',7.7],
['M54',283.775,-30.48333,'Globular cluster',7.7],
['M55',295,-30.96667,'Globular cluster',7],
['M56',289.15,30.18333,'Globular cluster',8.2],
['M57 Ring Nebula',283.4,33.03333,'Planetary nebula',9],
['M58',189.425,11.81667,'Barred spiral galaxy',9.8],
['M59',190.5,11.65,'Elliptical galaxy',9.8],
['M60',190.925,11.55,'Elliptical galaxy',8.8],
['M61',185.475,4.466667,'Spiral galaxy',9.7],
['M62',255.3,-30.11667,'Globular cluster',6.6],
['M63 Sunflower Galaxy',198.95,42.03333,'Spiral galaxy',8.6],
['M64 Blackeye Galaxy',194.175,21.68333,'Spiral galaxy',8.5],
['M65',169.725,13.08333,'Barred spiral galaxy',9.3],
['M66',170.05,12.98333,'Barred spiral galaxy',9],
['M67',132.6,11.81667,'Open cluster',6.9],
['M68',189.875,-26.75,'Globular cluster',8.2],
['M69',277.845,-32.35,'Globular cluster',7.7],
['M70',280.8,-32.3,'Globular cluster',8.1],
['M71',298.45,18.78333,'Globular cluster',8.3],
['M72',313.375,-12.53333,'Globular cluster',9.4],
['M73',314.725,-12.63333,'Asterism',5],
['M74',24.175,15.78333,'Spiral galaxy',9.2],
['M75',301.525,-21.91667,'Globular cluster',8.6],
['M76 Little Dumbbell Nebula',25.6,51.56667,'Planetary nebula',11.5],
['M77 Cetus A',40.675,0.01666667,'Spiral galaxy',8.8],
['M78',86.675,0.05,'Starforming nebula',8],
['M79',81.125,-24.55,'Globular cluster',8],
['M80',244.25,-22.98333,'Globular cluster',7.2],
['M81 Bode\'s Galaxy',148.9,69.06667,'Spiral galaxy',6.8],
['M82 Cigar Galaxy',148.95,69.68333,'Irregular galaxy',8.4],
['M83 Southern Pinwheel Galaxy',204.25,-29.86667,'Barred spiral galaxy',10.1],
['M84',186.275,12.88333,'Lenticular galaxy',9.3],
['M85',186.35,18.18333,'Lenticular galaxy',9.3],
['M86',186.55,12.95,'Lenticular galaxy',9.2],
['M87 Virgo A',187.7,12.4,'Elliptical galaxy',8.6],
['M88',188,14.41667,'Spiral galaxy',9.5],
['M89',188.925,12.55,'Elliptical galaxy',9.8],
['M90',189.2,13.16667,'Spiral galaxy',9.5],
['M91', 188.85, 14.5, 'Barred spiral galaxy', 10.2],
['M92',259.275,43.13334,'Globular cluster',6.5],
['M93',116.15,-23.86667,'Open cluster',6.2],
['M94',192.725,41.11666,'Spiral galaxy',8.1],
['M95',161,11.7,'Barred spiral galaxy',9.7],
['M96',161.7,11.81667,'Spiral galaxy',9.2],
['M97 Owl Neblua',168.7,55.01667,'Planetary nebula',11.2],
['M98',183.45,14.9,'Spiral galaxy',10.1],
['M99',184.7,14.41667,'Spiral galaxy',9.8],
['M100',185.725,15.81667,'Spiral galaxy',9.4],
['M101 Pinwheel Galaxy',210.825,54.35,'Spiral galaxy',7.7],
['M102 Spindle Galaxy',226.625,55.75,'Lenticular galaxy',10],
['M103',23.3,60.7,'Open cluster',7.4],
['M104 Sombrero Galaxy',190,-11.61667,'Spiral galaxy',8.3],
['M105',161.95,12.58333,'Elliptical galaxy',9.3],
['M106',184.75,47.3,'Spiral galaxy',8.3],
['M107',248.125,-13.05,'Globular cluster',8.1],
['M108',167.875,55.66667,'Spiral galaxy',10],
['M109',179.4,53.38334,'Barred spiral galaxy',9.8],
['M110',10.1,41.68333,'Dwarf elliptical galaxy',8]
];
    

    //  **********************************************************************
    //
    //
    //                              Functions
    //
    //
    //  **********************************************************************
    var viewData = MessierData;
    var selectedColor = "#adff2f";  // "#98FB98";
    var unselectedColor = "#008000";

    // This function initializes the wwt object and registers the wwtReady event
    // once the initialization is done the wwtReady event will be fired
    function initialize() {
        wwt = wwtlib.WWTControl.initControl("WWTCanvas");
        wwt.add_ready(wwtReady);
    }

    function createIndex() {
        var n;
        for (n = 0; n < viewData.length; n++)
            index[n] = n;
    } 
        
    function quicksort(from, to, x) {
        var v;
        var p;
        var less = [];
        var same = [];
        var more = [];
        var lc = 0;
        var sc = 0;
        var mc = 0;
        // Find central item v
        v = viewData[index[from]][x];
        // Count number of items less than, equal to, and greater than, v
        for (p = from; p <= to; p++) {
            if (viewData[index[p]][x] < v) {
                less[lc] = index[p];
                lc++;
            } else
                if (viewData[index[p]][x] == v) {
                same[sc] = index[p];
                sc++;
            } else
                if (viewData[index[p]][x] > v) {
                more[mc] = index[p];
                ++mc;
            }
        }
        if (document.getElementById("sortA").checked) {
            // Sort ascending
            for (p = 0; p < lc; p++)
                index[from + p] = less[p];
            for (p = 0; p < sc; p++)
                index[from + lc + p] = same[p];
            for (p = 0; p < mc; p++)
                index[from + lc + sc + p] = more[p];
            if (lc > 1)
                quicksort(from, from + lc - 1, x);
            if (mc > 1)
                quicksort(from + lc + sc, from + lc + sc + mc - 1, x);
        } else {
            // Sort descending
            for (p = 0; p < mc; p++)
                index[from + p] = more[p];
            for (p = 0; p < sc; p++)
                index[from + mc + p] = same[p];
            for (p = 0; p < lc; p++)
                index[from + mc + sc + p] = less[p];
            if (mc > 1)
                quicksort(from, from + mc - 1, x);
            if (lc > 1)
                quicksort(from + mc + sc, from + mc + sc + lc - 1, x);
        }
    }
    
    function sort(x) {
        quicksort(0, viewData.length - 1, x);
        clickFirst();
    }

    function reset() {
        if (document.getElementById("sortA").checked) {
            createIndex();
        } else {
            var n;
            for (n = 0; n < viewData.length; n++)
                index[n] = viewData.length - 1 - n;
        }
        clickFirst();
    }
    
    function showCurrent() {
        current = index[currentIndex];
        // Handle prev/next
        if (currentIndex >= 1) {
            document.getElementById('prev2').value = viewData[index[currentIndex - 1]][0];
            document.getElementById('prev1').value = viewData[index[currentIndex - 1]][3];
        } else {
            document.getElementById('prev2').value = "";
            document.getElementById('prev1').value = "";
        }
        if (currentIndex <= viewData.length - 2) {
            document.getElementById('next1').value = viewData[index[currentIndex + 1]][0];
            document.getElementById('next2').value = viewData[index[currentIndex + 1]][3];

        } else {
            document.getElementById('next1').value = "";
            document.getElementById('next2').value = "";
        }
        // Handle the current feature
        document.getElementById('feature').value = viewData[current][0];
        document.getElementById('RA').value = viewData[current][1];
        document.getElementById('Dec').value = viewData[current][2];
        document.getElementById('type').value = viewData[current][3] + "  ( mag " + viewData[current][4] + " )";
        //
        document.getElementById('feature').style.backgroundColor = selectedColor;
    }
    
    function clickFirst() {
        currentIndex = 0;
        showCurrent();
    }
    
    function clickLast() {
        currentIndex = viewData.length - 1;
        showCurrent();
    }
    
    function clickNext() {
        if (currentIndex < viewData.length - 1) {
            ++currentIndex;
            showCurrent();
        } else
            document.getElementById('feature').style.backgroundColor = unselectedColor;
    }
    
    function clickPrev() {
        if (currentIndex > 0) {
            --currentIndex;
            showCurrent();
        } else
            document.getElementById('feature').style.backgroundColor = unselectedColor;
    }

    function clickFind() {
        var s = document.getElementById('find').value;
        s = s.toLowerCase();
        // Find the first feature than has the search string as a substring
        if (s.length > 0) {
            var n = 0;
            var found = false;
            var s2 = "";
            while (n < viewData.length && !found) {
                s2 = viewData[index[n]][0];
                s2 = s2.toLowerCase();
                if (s2.indexOf(s, 0) != -1) {
                    currentIndex = n;
                    showCurrent();
                    found = true;
                } else
                    ++n;
            }
            if (!found)
                document.getElementById('feature').style.backgroundColor = unselectedColor;
        }
    }

    function nextType() {
        var currentType = viewData[index[currentIndex]][3];
        while (currentIndex < viewData.length - 1 && viewData[index[currentIndex]][3] == currentType)
            ++currentIndex;

        if (viewData[index[currentIndex]][3] != currentType)
            showCurrent(); else
            document.getElementById('feature').style.backgroundColor = unselectedColor;
    }
    
    function prevType() {
        var currentType = viewData[index[currentIndex]][3];
        while (currentIndex > 0 && viewData[index[currentIndex]][3] == currentType)
            --currentIndex;

        if (viewData[index[currentIndex]][3] != currentType)
            showCurrent(); else
            document.getElementById('feature').style.backgroundColor = unselectedColor;
    }
    
    function getZoomLevel() {
        var z = 1.0 * viewData[index[currentIndex]][4];
        z = z * z;
        return 1.5 - (z/100.0);
    }

    function showFeature() {
        var RA = 1.0 * document.getElementById('RA').value;
        var Dec = 1.0 * document.getElementById('Dec').value;

        if (RA < 0 || RA > 360) {
            document.getElementById('RA').value = "? (0 360)";
        } else
            if (Dec < -90.0 || Dec > 90.0) {
            document.getElementById('Dec').value = "? (-90 90)";
        } else {
            wwt.gotoRaDecZoom(RA, Dec, getZoomLevel(), false);
        }
    }
   
    // A simple function to toggle the settings
    // This function is called from the checkbox entries setup in the html table
    function toggleSetting(text) {
        switch (text) {
            case 'ShowUI':
                bShowUI = !bShowUI;
                wwt.hideUI(!bShowUI);
                break;
            case 'ShowCrosshairs':
                bShowCrosshairs = !bShowCrosshairs;
                wwt.settings.set_showCrosshairs(bShowCrosshairs);
                break;
        }
    }
  
    //
    // Slide show variables
    //

    var slidesOn = false;
    var bgc = null;
    var timeout;
    var milliseconds = 6000;
   
    function stopSlideShow() {
        slidesOn = false;
        document.getElementById('slide').value = " Start show ";
        document.getElementById('slide').style.backgroundColor = bgc;
        var newFov = 1.1 * wwt.get_fov();
        wwt.gotoRaDecZoom(wwt.getRA(), wwt.getDec(), newFov, true);
        clearTimeout(timeout);
    }

    function nextSlide() {

        if (slidesOn && currentIndex < viewData.length - 1) {
            ++currentIndex;
            showCurrent();
            showFeature();
            clearTimeout(timeout); // prevent any build up of messages
            timeout = setTimeout("nextSlide();", milliseconds);
        } else {
            stopSlideShow();
        }
    }

    function slideShow() {
        var n;
        if (slidesOn) {
            stopSlideShow();
        } else {
            slidesOn = true;
            document.getElementById('slide').value = " Stop show ";
            document.getElementById('slide').style.backgroundColor = selectedColor;
            showFeature();
            timeout = setTimeout("nextSlide();", 1000);

        }
    }
    // wwtArrived (similar to wwtReady) is a reserved name by the WWT Web Control 
    // This function is called when a Goto action comes to a halt
    function wwtArrived() {
        document.getElementById("t1").value = wwt.getRA();
        document.getElementById("t2").value = wwt.getDec();
    }

    // The wwtReady function is called by the WWT Web Control software
    // This function sets up the wwt object, and the initial defaults
    function wwtReady() {
        wwt.settings.set_showCrosshairs(bShowCrosshairs);
        wwt.hideUI(!bShowUI);

        createIndex();

        bgc = document.getElementById('slide').style.backgroundColor;
        clickFirst();
    }
    //  **********************************************************************
    //
    //
    //                              Script
    //
    //
    //  **********************************************************************
    </script>
 
</head>
 
<body onload="initialize()" >
    <!-- The body section creates a table with two columns. The first contains the -->
    <!-- WWTControl object that is the WWT web client. And the second a table within-->
    <!-- the table, containing some buttons and checkboxes.-->
    <table border="2" bgcolor="black">
        <tr>
            <td>
                <div id="WorldWideTelescopeControlHost">
                    <div id="WWTCanvas" style="width: 750px; height: 750px; border-style: none; border-width: 0px;">
                    </div>
                </div>
            </td>
            <td>
                <table border="2" cellspacing="4" cellpadding="4" bgcolor="#ffd700">
                    <tr>
                        <th colspan="2">
                            <h2>
                                 The Messier Catalog</h2>
                        </th>
                    </tr>

                    <tr>
                        <td>
                            Previous
                        </td>
                        <td>
                            <input id="prev2" type="text" readonly="readonly" style="font-style: italic" /><br />
                            <input id="prev1" type="text" readonly="readonly" style="font-style: italic" />
                        </td>
                    </tr>
                    <tr>
                        <td style="font-weight: bold">
                            Feature
                        </td>
                        <td>
                            <input id="feature" type="text" value="Zero Zero" readonly="readonly" style="font-weight: bold" size="30"/><br />
                            <input id="type" type="text" value="Zero RA Dec" readonly="readonly" style="font-weight: bold" size="30" />
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Next
                        </td>
                        <td>
                            <input id="next1" type="text" readonly="readonly" style="font-style: italic" /><br />
                            <input id="next2" type="text" readonly="readonly" style="font-style: italic" />
                        </td>
                    </tr>
                    <tr>
                        <th colspan="2">
                            <input type="button" id="first" value="First   " onclick="clickFirst();" />&nbsp;
                            <input type="button" id="prev" value="  Prev  " onclick="clickPrev();" />&nbsp;
                            <input type="button" id="next" value="  Next  " onclick="clickNext();" />&nbsp;
                            <input type="button" id="last" value="   Last" onclick="clickLast();" />
                        </th>
                    </tr>
                    <tr>
                        <th colspan="2">
                            <input type="button" id="Button2" value=" Prev type  " onclick="prevType();" />&nbsp;
                            <input type="button" id="Button3" value=" Next type  " onclick="nextType();" />
                        </th>
                    </tr>
                                        <tr>
                        <th colspan="3">
                            <input type="button" id="findfeature" value=" Find feature " onclick="clickFind();" />
                            <input type="text" id="find" value="" />
                        </th>
                    </tr>
                                        <tr>
                        <th colspan="2">
                            <input id="sort2" type="button" value="Sort (name)" onclick="reset();" />&nbsp;
                            <input id="sort1" type="button" value="Sort (mag)" onclick="sort(4);" />&nbsp;
                            <input id="sort3" type="button" value="Sort (type)" onclick="sort(3);" />&nbsp;
                            &nbsp;Asc&nbsp;<input id="sortA" type="checkbox" checked="checked" />
                        </th>
                    </tr>
                    <tr>
                        <th colspan="2">
                            <input type="button" id="goto" value=" Goto " style="font-size: x-large" onclick="showFeature();" />
                        </th>
                    </tr>
                    <tr>
                        <td>
                            Slide show:
                        </td>
                        <td>
                            <input type="button" id="slide" value=" Start show " style="font-size:large" onclick="slideShow();" />
                        </td>
                    </tr>


                    <tr>
                        <td style="text-align: right">
                            RA:
                        </td>
                        <td>
                            <input id="RA" type="text" value="0" size="5"/>
                           
                        </td>
                    </tr>
                    <tr>
                        <td style="text-align: right">
                            Dec:
                        </td>
                        <td>
                            <input id="Dec" type="text" value="0" size="5"/>
                           
                        </td>
                    </tr>
                   <tr>
                        <th colspan="2">
                            View
                        </th>
                    </tr>
                    <tr>
                        <td>
                            View RA
                        </td>
                        <td>
                            <input id="t1" type="text" readonly="readonly"/>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            View Dec
                        </td>
                        <td>
                            <input id="t2" type="text" readonly="readonly"/>
                        </td>
                    </tr>
                    <tr>
                        <th colspan="2">
                            Settings
                        </th>
                    </tr>
<!--                    <tr>
                        <td>
                            Show UI
                        </td>
                        <td>
                            <input id="UI" type="checkbox" checked="checked" onclick="toggleSetting('ShowUI');" />
                        </td>
                    </tr>-->
                    <tr>
                        <td>
                            Show Crosshairs
                        </td>
                        <td>
                            <input id="Crosshairs" type="checkbox" checked="checked" onclick="toggleSetting('ShowCrosshairs');" />
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</body>
</html>

